﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using log4net;

namespace CSharpExecutor
{
    public class PreProcessor
    {
        #region Variables

        private ILog _log;

        #endregion

        #region Constructors

        public PreProcessor()
        {
            _log = LogManager.GetLogger(typeof(PreProcessor));

            Actions = new Dictionary<string, Action<List<string>, int, Match>>();

            // Add the #include directive:
            Actions.Add(@"^\#include\s+\""(?<include>\w[\d\w\.]*)\""\s*$",
                (lines, index, match) => lines.Insert(index, ProcessFile(match.Groups["include"].Value)));
        }

        #endregion

        #region Properties

        /// <remarks>
        /// Dictionary key = regular expression.
        /// Action parameters: script lines, script lines index, regular expression match
        /// </remarks>
        public Dictionary<string, Action<List<string>, int, Match>> Actions { get; private set; }

        #endregion

        #region Methods

        public string ProcessFile(string filename)
        {
            _log.Info("Pre-processing a file.");

            return ProcessLines(File.ReadAllLines(filename).ToList());
        }

        public string ProcessText(string text)
        {
            _log.Info("Pre-processing a text block.");

            return ProcessLines(text.Split('\n').ToList());
        }

        private string ProcessLines(List<string> lines)
        {
            for (var index = 0; index < lines.Count; index++)
            {
                foreach (var action in Actions)
                {
                    var match = Regex.Match(lines[index], action.Key);
                    if (match.Success)
                    {
                        lines[index] = lines[index].Insert(0, "//");
                        action.Value(lines, index, match);
                        break;
                    }
                }
            }

            return string.Join("\n", lines.ToArray());
        }

        #endregion
    }
}